﻿#pragma once
#include "yzrutil.h"
#include "DSP.h"
#include "RingBuffer.h"
#include "BufferDelayer.h"

namespace yzrilyzr_dsp{
	ECLASS(AllPassFilter, public DSP){
	private:
	RingBufferSample buffer;
	u_sample delayIndex=0;
	public:
	u_time_ms delayTimeMs=0;
	u_normal_11 gain=0;
	BufferDelayer::DelayFunction delayFunction=BufferDelayer::linearDelay;
	AllPassFilter(){
		registerParamTimeMs("DelayTime", &delayTimeMs);
		registerParamNormal11("Gain", &gain);
	}
	AllPassFilter(u_time_ms delayTimeMs, u_normal_11 gain) :delayTimeMs(delayTimeMs), gain(gain){}
	void init(u_sample_rate sampleRate)override{
		delayIndex=RingBufferUtil::ms2DelayIndex(delayTimeMs, sampleRate);
		buffer.ensureCapacity(delayIndex);
	}
	u_sample procDsp(u_sample input) override{
		u_sample delayed=delayFunction(buffer, delayIndex);
		u_sample output=-input * gain + delayed;
		buffer.write(input + delayed * gain);
		return output;
	}
	void resetMemory()override{
		buffer.fill(0);
	}
	std::shared_ptr<DSP> cloneDSP()override{
		return std::make_shared < AllPassFilter>(delayTimeMs, gain);
	}
	void cloneParam(DSP * obj1)override{
		if(auto other=dynamic_cast<AllPassFilter *>(obj1)){
			delayTimeMs=other->delayTimeMs;
			gain=other->gain;
			delayFunction=other->delayFunction;
		}
	}
	yzrilyzr_lang::String toString()const override;
	};
}